#!/bin/sh /etc/rc.common

START=99

IPSEC_SECRETS_FILE=/etc/ipsec.secrets
IPSEC_CONN_FILE=/etc/ipsec.conf

add_rule() {
	if [ "$useLanDHCP" = 0 ]; then
		iptables -t nat -I POSTROUTING -s ${vt_clientip%.*}.0/24 -m comment --comment "IPSec VPN Server" -j MASQUERADE
		iptables -I forwarding_rule -s ${vt_clientip%.*}.0/24 -m comment --comment "IPSec VPN Server" -j ACCEPT
	fi
	iptables -I forwarding_rule -m policy --dir in --pol ipsec --proto esp -m comment --comment "IPSec VPN Server" -j ACCEPT
	iptables -I forwarding_rule -m policy --dir out --pol ipsec --proto esp -m comment --comment "IPSec VPN Server" -j ACCEPT
	iptables -I INPUT -p udp -m multiport --dports 500,4500 -m comment --comment "IPSec VPN Server" -j ACCEPT
}

del_rule() {
	iptables -D INPUT -p udp -m multiport --dports 500,4500 -m comment --comment "IPSec VPN Server" -j ACCEPT 2> /dev/null
	ipsec_nums=$(iptables -t nat -n -L POSTROUTING 2>/dev/null | grep -c "IPSec VPN Server")
	if [ -n "$ipsec_nums" ]; then
		until [ "$ipsec_nums" = 0 ]
		do
			rules=$(iptables -t nat -n -L POSTROUTING --line-num 2>/dev/null | grep "IPSec VPN Server" | awk '{print $1}')
			for rule in $rules
			do
				iptables -t nat -D POSTROUTING $rule 2> /dev/null
				break
			done
			ipsec_nums=$(expr $ipsec_nums - 1)
		done
	fi
	nums=$(iptables -n -L forwarding_rule 2>/dev/null | grep -c "IPSec VPN Server")
	if [ -n "$nums" ]; then
		until [ "$nums" = 0 ]
		do
			rules=$(iptables -n -L forwarding_rule --line-num 2>/dev/null | grep "IPSec VPN Server" | awk '{print $1}')
			for rule in $rules
			do
				iptables -D forwarding_rule $rule 2> /dev/null
				break
			done
			nums=$(expr $nums - 1)
		done
	fi
}

gen_include() {
	echo '#!/bin/sh' > /var/etc/ipsecvpn.include
	extract_rules() {
		echo "*$1"
		iptables-save -t $1 | grep "IPSec VPN Server" | \
		sed -e "s/^-A \(INPUT\)/-I \1 1/"
		echo 'COMMIT'
	}
	cat <<-EOF >> /var/etc/ipsecvpn.include
		iptables-save -c | grep -v "IPSec VPN Server" | iptables-restore -c
		iptables-restore -n <<-EOT
		$(extract_rules filter)
		$(extract_rules nat)
		EOT
	EOF
	return 0
}

setup_login() {
	config_get enabled $1 enabled
	[ "$enabled" -eq 0 ] && return 0
	config_get username $1 username
	config_get password $1 password
	[ -n "$username" ] || return 0
	[ -n "$password" ] || return 0
	local ikev2enabled=$(uci -q get ipsec.@service[0].ikev2enabled)
	if [ "$ikev2enabled" = 1 ]; then
		echo "$username %any : EAP '$password'" >> $IPSEC_SECRETS_FILE
	fi
	echo "$username : XAUTH '$password'" >> $IPSEC_SECRETS_FILE
}

start() {
	local vt_enabled=$(uci -q get ipsec.@service[0].enabled)
	[ "$vt_enabled" = 0 ] && return 1
	
	local vt_clientip=$(uci -q get ipsec.@service[0].clientip)
	
	local vt_clientdns=$(uci -q get ipsec.@service[0].clientdns)
	
	local lan_ip=$(uci get network.lan.ipaddr)
	[ -z "$vt_clientdns" ] && local vt_clientdns="8.8.4.4"
	
	local vt_secret=$(uci -q get ipsec.@service[0].secret)
	
	local useLanDHCP=$(uci -q get ipsec.@service[0].useLanDHCP)
	local lanDHCPServer=$(uci -q get ipsec.@service[0].lanDHCPServer)
	
	local ikev2enabled=$(uci -q get ipsec.@service[0].ikev2enabled)
	
	if [ "$useLanDHCP" = 1 ]; then
		#使用局域网IP
		local vt_cfg_rightsourceip="%dhcp";
	else
		local vt_cfg_rightsourceip=$vt_clientip;
	fi
	
	cat > $IPSEC_CONN_FILE <<EOF
# ipsec.conf - strongSwan IPsec configuration file

# basic configuration

config setup
    # strictcrlpolicy=yes
    uniqueids=never

# Add connections here.

conn xauth_psk
	keyexchange=ikev1
	ike=aes128-sha1-modp2048,aes128-sha1-modp1024,3des-sha1-modp1024,3des-sha1-modp1536
	esp=aes128-sha1,3des-sha1
	left=%defaultroute
	leftauth=psk
	leftsubnet=0.0.0.0/0
	right=%any
	rightauth=psk
	rightauth2=xauth
	rightsourceip=$vt_cfg_rightsourceip
	rightdns=$vt_clientdns
	auto=add
EOF

if [ "$ikev2enabled" = 1 ]; then
	local routerDomain=$(uci -q get ipsec.@service[0].routerDomain)
cat >> $IPSEC_CONN_FILE <<EOF
conn ikev2-eap
	keyexchange=ikev2
	ike=aes256-sha256-modp1024,3des-sha1-modp1024,aes256-sha1-modp1024,aes256-aes128-sha256-sha1-modp3072-modp2048-modp1024
	esp=aes256-sha256,3des-sha1,aes256-sha1!
	rekey=no
	leftauth=pubkey                           # 服务器端使用公钥方式验证
	leftcert=SERVER.crt  # 证书文件
	leftsendcert=always
	leftid=@$routerDomain                   # 需要和申请CA签发证书中的域名一致
	leftsubnet=0.0.0.0/0
	rightsourceip=$vt_cfg_rightsourceip
	rightauth=eap-mschapv2                    # 客户端使用eap方式验证
	rightsendcert=never
	eap_identity=%any
	rightdns=$vt_clientdns
	auto=add
EOF
fi
	cat > /etc/ipsec.secrets <<EOF
# /etc/ipsec.secrets - strongSwan IPsec secrets file
: PSK "$vt_secret"
EOF
if [ "$ikev2enabled" = 1 ]; then
	cat >> /etc/ipsec.secrets <<EOF
: RSA KEY.key
EOF
fi
	add_rule
	
	config_load ipsec
	config_foreach setup_login users
	
	local lanDHCPconfig="no"
	if [ "$useLanDHCP" = 1 ]; then
		local lanDHCPconfig="yes"
	fi
	
	cat > /etc/strongswan.d/charon/dhcp.conf <<EOF
dhcp {

    # Always use the configured server address.
    # force_server_address = no

    # Derive user-defined MAC address from hash of IKE identity and send client
    # identity DHCP option.
    # identity_lease = no

    # Interface name the plugin uses for address allocation.
    interface = br-lan

    # Whether to load the plugin. Can also be an integer to increase the
    # priority of this plugin.
    load = $lanDHCPconfig

    # DHCP server unicast or broadcast IP address.
    server = $lanDHCPServer

    # Use the DHCP server port (67) as source port when a unicast server address
    # is configured.
    # use_server_port = no

}
EOF
	
	/usr/lib/ipsec/starter --daemon charon --nofork > /dev/null 2>&1 &
	gen_include
}

stop() {
	ps -w | grep "/usr/lib/ipsec" | grep -v "grep" | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1
	del_rule
	rm -rf /var/etc/ipsecvpn.include
}